# -*-coding=utf-8 -*-
"""
    @author:sirius
    @time:2017.10.19
"""
import sys
import pandas as pd
from texttable import Texttable
# 协同过滤算法
from coll_filter import getAppList, getEventList, recommendByUserFC, userFC, get_feature
from sklearn.metrics import classification_report

# 特征矩阵常量
P_MATRIX = [('workday', 'Morning'), ('workday', 'Noon'), ('workday', 'Afternoon'), ('workday', 'Evening'), ('workday', 'Night'), ('holiday', 'Morning'), ('holiday', 'Noon'), ('holiday', 'Afternoon'), ('holiday', 'Evening'), ('holiday', 'Night')]

def similarityFuse(userList, itemList, timezone):
     '''基于条件概率的相似度融合框架'''
     # 定义US数据集分子
     US_numerator = 0.0
     # 定义IS数据集分子
     IS_numerator = 0.0
     # 定义UIS数据集分子
     UIS_numerator = 0.0
     # 定义US数据集分母
     US_denominator = 0.0
     # 定义IS数据集分母
     IS_denominator = 0.0
     # 定义UIS数据集分母
     UIS_denominator = 0.0
     # 定义US数据集条件概率
     ProbabilityUIS = 0.0
     # 定义IS数据集条件概率
     ProbabilityUS = 0.0
     # 定义UIS数据集条件概率
     ProbabilityIS = 0.0
     UIS = []
     usList = []
     isList = []
     uisList = []
     recommand_list = []
     # 获取特征矩阵数据
     matrix = get_feature()
     # US数据集IS数据集连接
     for user in userList:
          for item in itemList:
               for p_matrix in P_MATRIX:
                    if float(user[1]) == float(item[0]):
                         for m in matrix[user[1]]:
                              UIS.append([user[0], user[1], m])
                    elif matrix[user[1]][p_matrix] == matrix[item[0]][p_matrix]:
                         UIS.append([user[0], user[1], matrix[user[1]][p_matrix]])
                         UIS.append([item[1], item[0], matrix[item[0]][p_matrix]])

     for user in userList:
          # 获取US数据集该时间区间所打开的应用个数
          tz_USLen = len(matrix[user][timezone])
          # 获取应用启动事件总个数
          set_USLen = 0
          for tz in matrix[user]:
               set_USLen += len(tz)
          # 计算依赖US数据集条件概率分子
          US_numerator += user[0]*tz_USLen
          # 计算依赖US数据集条件概率分母
          US_denominator += user[0]*set_USLen
     for item in itemList:
          # 获取IS数据集该时间区间所打开的应用个数
          tz_ISLen = len(matrix[item][timezone])
          # 获取应用启动事件总个数
          set_ISLen = 0
          for tz in matrix[user]:
               set_ISLen += len(tz)
          # 计算依赖IS数据集条件概率分子
          IS_numerator += user[0]*tz_ISLen
          # 计算依赖IS数据集条件概率分母
          IS_denominator += user[0]*set_ISLen
     for uis in UIS:
          # 计算依赖UIS数据集条件概率
          for tz in UIS:
               if tz[2] == timezone:
                    UIS_numerator += tz[0]
               UIS_denominator += tz[0]
     # 条件概率
     ProbabilityUS = US_numerator/US_denominator
     ProbabilityIS = IS_numerator/IS_denominator
     ProbabilityUIS = UIS_numerator/UIS_denominator

     for uSimilarity in userList:
          usList.append([uSimilarity[0]/ProbabilityUS, uSimilarity[1]])
     for iSimilarity in itemList:
          isList.append([iSimilarity[0]/ProbabilityIS, iSimilarity[1]])
     for uiSimilarity in UIS:
          uisList.append([(uiSimilarity[0]+uiSimilarity[2])/ProbabilityIS, uiSimilarity[1]])

     for user in userList:
          for item in itemList:
               for uis in UIS:
                    if user[1] == item[1] and user[1] == uis[1]:
                         recommand_list.append([(ProbabilityUIS*0.7*0.5+ProbabilityIS*0.3*0.5+ProbabilityUS*0.7*0.5), uis[2]])

     recommand_list.sort(reverse = True)
     return recommand_list[:5]

#从这里开始运行
if __name__ == '__main__':
     reload(sys)
     sys.setdefaultencoding('utf-8')
     # 目标用户
     targetUser = '5988.0'
     # 事件序列
     event = 0
     # 命中次数
     hitNum = 0
	 #获取所有应用的列表,所有应用id到应用名字的键值对
     dictAppId2Info = getAppList("./cache/app_rec_sys.csv")
     EventList = getEventList("./cache/app_rec_sys.csv", targetUser)
     # 获取特征矩阵
     features = get_feature()
     # appEventList = getEventList("./cache/app_rec_sys.csv", '5988')
     # dictAppId2Info = getAppList("./cache/app_rec_sys.csv")
     # 读取周期律相似度
     file_neighbors = open('./period/md_cache/neighbors.txt', 'r')
     try:
          period_neighbors = file_neighbors.read()
     finally:
          file_neighbors.close()
     # print neighbors
     # 将字符串转换为列表
     period_neighbors = eval(period_neighbors)
     # 计算用户相似度，输入参数：1. 数据集文件 2. 目标用户ID 3. 邻居个数
     listUser2Score, dictItem2Users, neighbors = userFC("./cache/app_rec_sys.csv", targetUser, 5)
     event = 0

     for timezone in P_MATRIX:
          for feature in features[targetUser][timezone]:
               # 相似度融合
               listRecommendAppId = similarityFuse(neighbors, period_neighbors, timezone)
               # 根据用户相似度进行推荐，输入参数：1. 用户-相似度列表 2. app-用户字典 3. 用户ID 4. 邻居列表 5. 事件序列
               listRecommendAppId1, user_app, items_app = recommendByUserFC(listUser2Score, dictItem2Users, targetUser, neighbors, timezone)
               neighbors_id=[ i[1] for i in neighbors]
               table = Texttable()
               table.set_deco(Texttable.HEADER)
               table.set_cols_dtype(['t', 't', 't'])
               table.set_cols_align(["l", "l", "l"])
               rows=[]
               rows.append([u"APP NAME",u"Event ID", u"from userid"])
               #打印推荐列表的前20项数据，listRecommendAppId里边存储的仅仅是id
               for app_id in listRecommendAppId[:5]:
                    from_user=[]
                    for user_id in items_app[app_id[1]]:
                         if user_id in neighbors_id:
                              from_user.append(user_id)
                    # dictMovieId2Info[app_id][0]表示应用ID dictMovieId2Info[app_id][1]类别ID
                    rows.append([app_id[1],dictAppId2Info[app_id[1]],from_user])
               table.add_rows(rows)
               print table.draw()
               print "用户%s:%s"%(targetUser, EventList[event+1])
               # print EventList[event+1]
               # print [k[1] for k in listRecommendAppId]
               if EventList[event+1] in [k[1] for k in listRecommendAppId]:
                    hitNum += 1
               event += 1

     print "预测准确度：",float(hitNum)/event
